package cn.wolfcode.luowowo.service.impl;


import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.query.StrategyCatalogQuery;
import cn.wolfcode.luowowo.repository.StrategyCatalogRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyCatalogService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.Catalogs;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class StrategyCatalogServiceImpl implements IStrategyCatalogService {



    @Autowired
    private StrategyCatalogRepository strategyCatalogRepository;

    @Autowired
    private IDestinationService destinationService;

    @Autowired
    private IStrategyService strategyService;

    @Autowired
    private MongoTemplate template;



    @Override
    public StrategyCatalog get(String id) {
        return strategyCatalogRepository.findById(id).orElse(null);
    }

    @Override
    public List<StrategyCatalog> list() {
        return strategyCatalogRepository.findAll();
    }

    @Override
    public void save(StrategyCatalog strategyCatalog) {
        Destination destination = destinationService.get(strategyCatalog.getDestId());
        strategyCatalog.setDestName(destination.getName());
        strategyCatalogRepository.save(strategyCatalog);
    }

    @Override
    public void update(StrategyCatalog strategyCatalog) {
        Destination destination = destinationService.get(strategyCatalog.getDestId());
        strategyCatalog.setDestName(destination.getName());
        strategyCatalogRepository.save(strategyCatalog);
    }

    @Override
    public void delete(String id) {
        strategyCatalogRepository.deleteById(id);
    }

   

    @Override
    public Page<StrategyCatalog> query(StrategyCatalogQuery qo) {
        // 查询条件
        Query query = new Query();

        // 拼接高级查询条件
        if (StringUtils.hasLength(qo.getKeyword())) {
            query.addCriteria(Criteria.where("name").regex(".*"+qo.getKeyword()+".*"));
        }

        // 列表数据
        PageRequest request = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, "_id");

        return DBHelper.query(template,StrategyCatalog.class,query,request);
    }

    @Override
    public List<Catalogs> getStrategyCateLogs() {

        // 1. 创建管道
        TypedAggregation<StrategyCatalog> gd = Aggregation.newAggregation(StrategyCatalog.class, Aggregation.group("destName")
                .push("name").as("names")
                .push("id").as("ids")
        );
        // 2. 查询
        AggregationResults<Map> aggregate = template.aggregate(gd, Map.class);

        // 3. 获取结果集中的数据  getMappedResults
        List<Map> maps = aggregate.getMappedResults();

        // 4. 循环将数据放入自定义类
        // 提前准备好list
        List<Catalogs> catalogss = new ArrayList<>();

        for(Map map  : maps){
            // 每次创建一个空对象
            Catalogs catalogs = new Catalogs();
            // 开始放数据 destName
            catalogs.setDestName(map.get("_id").toString());        // 返回结果给的名字
            // 继续放下级数据
            List<Object> names = (List<Object>) map.get("names");   // 因为Object没法循环 ,强转为 list
            List<Object> ids = (List<Object>)map.get("ids");        // 同理可得

            List<Map<String, Object>> mapss = new ArrayList<>();     // 准备空数据格式的 mapList
            // 因为names 和 ids 的数据是对应的  所以循环的时候取任意一个做终止条件都可以
            for(int i = 0; i < ids.size(); i++){
                // 每次循环创建一个空map,用于存放 name 和 id
                Map<String, Object>  mp = new HashMap<>();
                mp.put("name",names.get(i).toString());
                mp.put("id",ids.get(i).toString());
                // 每次往准备好的 mapss 中压入数据
                mapss.add(mp);
            }
            // 把循环存入好的下级数据,放入集合 mapList
            catalogs.setMapList(mapss);
            // 再把 mapList 放入提前准备好的空 list
            catalogss.add(catalogs);
        }

        return catalogss;

    }

    @Override
    public List<StrategyCatalog> findByDestId(String destId) {
        // 首先查出该目的地下所有的攻略分类
        List<StrategyCatalog> strategyCatalogs = strategyCatalogRepository.findByDestId(destId);
        // 循环攻略分类,把每个攻略分类下的攻略放入对象
        for (StrategyCatalog strategyCatalog : strategyCatalogs) {
            strategyCatalog.setStrategies(strategyService.findByCatalogId(strategyCatalog.getId()));
        }
        return strategyCatalogs;
    }


}
